import { createNextAnimateFrameEvent } from "xbsj-base"
import { HeightModifyEditing } from "../base"
import { ESCesiumViewer } from "@czmSrc/ESCesiumViewer"
import { equalsN3, ESClassification, ESJEditingMode, ESJVector3D, ESPolygonFence, ESSceneObject, getMinMaxCorner } from "earthsdk3"
import { BaseEditingWrapper } from "./BaseEditingWrapper";
export class HeightModifyEditingWrapper extends BaseEditingWrapper {
    static readonly type = this.registerEditing("ESCesiumViewer", ESJEditingMode.HeightModify, this);
    constructor(sceneObject: ESSceneObject, czmViewer: ESCesiumViewer) {
        super(sceneObject, czmViewer, true);
        if (!czmViewer.viewer) return;
        const heightModifyEditing = this.currentEditing = this.ad(new HeightModifyEditing(czmViewer));
        do {
            if (Reflect.has(sceneObject, 'points')) {
                const hasExtrudedHeight = Reflect.has(sceneObject, 'extrudedHeight');
                const hasHeight = Reflect.has(sceneObject, 'height');
                //@ts-ignore
                const perPositionHeight = Reflect.has(sceneObject, 'perPositionHeight') ? sceneObject.perPositionHeight : !hasExtrudedHeight;
                const relativeHeight = sceneObject instanceof ESClassification || sceneObject instanceof ESPolygonFence
                //@ts-ignore
                // 获取中心点做最低点
                let bottom = getMinMaxCorner(sceneObject.points).center;
                let top: ESJVector3D = [...bottom];
                //@ts-ignore ESClassification 高度是相对高度
                let extraHeight = relativeHeight ? sceneObject.points[0][2] : 0;
                if (perPositionHeight) {
                    if (hasExtrudedHeight) {
                        //@ts-ignore
                        top[2] = sceneObject.extrudedHeight
                    } else {
                        //@ts-ignore
                        top[2] = sceneObject.height + extraHeight;
                    }
                } else {
                    //@ts-ignore
                    hasHeight && (bottom[2] = sceneObject.height);
                    //@ts-ignore
                    hasExtrudedHeight && (top[2] = sceneObject.extrudedHeight);
                }
                // 初始化
                heightModifyEditing.startPosition = bottom;
                heightModifyEditing.distance = top[2] - bottom[2];
                heightModifyEditing.moveWithFirstPosition = false;
                let lastPosition: ESJVector3D = [...bottom];
                this.ad(heightModifyEditing.positionsChanged.don(() => {
                    if (heightModifyEditing.positions.length !== 2) return;
                    if (perPositionHeight) {
                        //@ts-ignore
                        sceneObject.points = sceneObject.points.map((item: ESJVector3D) => {
                            return [item[0], item[1], item[2] + heightModifyEditing.positions[0][2] - lastPosition[2]];
                        });
                        //@ts-ignore
                        if (hasExtrudedHeight) {
                            //@ts-ignore
                            sceneObject.extrudedHeight = heightModifyEditing.positions[1][2];
                        } else {
                            //@ts-ignore
                            hasHeight && (sceneObject.height = heightModifyEditing.positions[1][2] - (relativeHeight ? heightModifyEditing.positions[0][2] : 0));
                        }
                    } else {
                        //@ts-ignore
                        hasHeight && (sceneObject.height = heightModifyEditing.positions[0][2]);
                        //@ts-ignore
                        hasExtrudedHeight && (sceneObject.extrudedHeight = heightModifyEditing.positions[1][2]);
                    }
                    lastPosition = [...heightModifyEditing.positions[0]];
                }));
                break;
            }
            this.supportEditing = false;
            return;
        } while (false);
        heightModifyEditing.init();
        heightModifyEditing.enabled = true;
        const event = this.ad(createNextAnimateFrameEvent(
            heightModifyEditing.enabledChanged,
            heightModifyEditing.startPositionChanged,
        ))
        this.ad(event.don(() => {
            if (!heightModifyEditing.enabled || !heightModifyEditing.startPosition || equalsN3(heightModifyEditing.startPosition, [0, 0, 0])) {
                this.destroy();
            }
        }));
    }
}